# Always print this out before your assignment
sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 11.5.2

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] knitr_1.33

loaded via a namespace (and not attached):
 [1] compiler_4.1.1  here_1.0.1      fastmap_1.1.0   rprojroot_2.0.2 htmltools_0.5.2 tools_4.1.1     yaml_2.2.1      rmarkdown_2.10 
 [9] xfun_0.25       digest_0.6.27   rlang_0.4.12    evaluate_0.14  
getwd()
[1] "/Users/darron/Downloads"

# load all your libraries in this chunk 
library('dplyr')
library('tidyverse')
library('utils')
library('rsample')
library('glmnet')
library('glmnetUtils')
library('forcats')
library('rsample')
library('ggplot2')
library('sjPlot')
library('Publish')
library('data.table')
library('psych')
library('partykit')
library('PerformanceAnalytics')
library('rpart')
library('rpart.plot')
library('maptree')
library('randomForestExplainer')
library('rpart')
library('visNetwork')
library('caret')
library('ISLR')


# note, do not run install.packages() inside a code chunk. install them in the console outside of a code chunk. 
plays <- read.csv(here::here("Datasets", "plays.csv"))
pff <- read.csv(here::here("Datasets", "PFFscoutingdata.csv"))
head(pff)
NA

DF <- full_join(x = plays,
                 y = pff,
                 by = "gameId")

DF2 = select(DF, -5:-7, -10:-21, -25:-29, -32:-43)

DF2 %>% drop_na()

DF2$return_type[DF2$kickReturnYardage < 20] = "Short"
DF2$return_type[DF2$kickReturnYardage > 20 & DF2$kickReturnYardage < 50] = "Medium"
DF2$return_type[DF2$kickReturnYardage > 50] = "Long"

FinalDF <- data.frame(DF2, stringsAsFactors = TRUE) %>%
  drop_na() %>%
  mutate(return_type = as.factor(return_type),
         kickType = as.factor(kickType),
         kickContactType = as.factor(kickContactType))
head(FinalDF)
NA

summary(FinalDF)
     gameId              playId.x    playDescription       quarter      specialTeamsPlayType specialTeamsResult   kickLength   
 Min.   :2018090600   Min.   :  35   Length:41701       Min.   :1.000   Length:41701         Length:41701       Min.   : 2.00  
 1st Qu.:2018112508   1st Qu.: 886   Class :character   1st Qu.:1.000   Class :character     Class :character   1st Qu.:48.00  
 Median :2019102703   Median :1987   Mode  :character   Median :2.000   Mode  :character     Mode  :character   Median :56.00  
 Mean   :2019048212   Mean   :1986                      Mean   :2.444                                           Mean   :54.58  
 3rd Qu.:2020092712   3rd Qu.:2974                      3rd Qu.:3.000                                           3rd Qu.:63.00  
 Max.   :2021010315   Max.   :5456                      Max.   :5.000                                           Max.   :80.00  
                                                                                                                               
 kickReturnYardage   playResult        hangTime     kickType  kickContactType return_type   
 Min.   :-16.00    Min.   :-35.00   Min.   :1.220   A:12187   CC     :26944   Long  :13150  
 1st Qu.:  5.00    1st Qu.: 35.00   1st Qu.:4.080   N:29480   BF     : 7218   Medium:11483  
 Median : 14.00    Median : 41.00   Median :4.380   R:   34   BB     : 2119   Short :17068  
 Mean   : 15.08    Mean   : 40.18   Mean   :4.317             OOB    : 1937                 
 3rd Qu.: 23.00    3rd Qu.: 48.00   3rd Qu.:4.630             CFFG   : 1222                 
 Max.   :104.00    Max.   : 82.00   Max.   :5.690             MBDR   :  995                 
                                                              (Other): 1266                 

ggplot(data = FinalDF, aes(x = hangTime, y = kickLength)) + geom_point()


ggplot(data = FinalDF, aes(x = kickLength, y = kickReturnYardage)) + geom_point()


ggplot(data = FinalDF, aes(x = return_type)) + geom_bar()

df_split <- initial_split(FinalDF, prop = 0.75)
df_train <- training(df_split)
df_test <- testing(df_split)

dim(df_train)
[1] 31275    13
dim(df_test)
[1] 10426    13
mod1 <- lm(kickReturnYardage ~ kickLength + hangTime + kickContactType + playResult,
           data = df_train)

plot(x = predict(mod1), y = df_train$kickReturnYardage,
     xlab='Predicted Values',
     ylab='Actual Values',
     main='Predicted vs. Actual Values (Training Model)',
     col= 1)
abline(a = 0, b = 1)


print(mean((df_train$kickReturnYardage - predict(mod1))^2))
[1] 12.93302
plot(x = predict(mod1, newdata = df_test), y = df_test$kickReturnYardage,
     xlab='Predicted Values',
     ylab='Actual Values',
     main='Predicted vs. Actual Values (Testing Model)',
     col= 1)
abline(a = 0, b = 1)


print(mean((df_test$kickReturnYardage - predict(mod1))^2))
Warning in df_test$kickReturnYardage - predict(mod1) :
  longer object length is not a multiple of shorter object length
[1] 336.3096
#decision tree 1

#tree_mod_train <- ctree(return_type ~ kickLength + hangTime ,
    #                    data = df_train)



#print(tree_mod_train)
#plot(tree_mod_train) 
library('sparkline')


summary_mod_rpart <- rpart(return_type ~ kickLength + hangTime,
                           data = df_train,
                           method = "class",
                           control = list(cp = 0,
                                          minsplit = 10,
                                          maxdepth = 5))
summary_mod_rpart$cptable
            CP nsplit rel error    xerror        xstd
1 0.3887059332      0 1.0000000 1.0000000 0.004691750
2 0.0044539222      1 0.6112941 0.6112941 0.004588429
3 0.0035091508      3 0.6023862 0.6026022 0.004574035
4 0.0004049020      5 0.5953679 0.5954759 0.004561804
5 0.0001619608      7 0.5945581 0.5963397 0.004563308
6 0.0001079739      9 0.5942342 0.5966096 0.004563776
7 0.0000000000     11 0.5940182 0.5973115 0.004564992
plotcp(summary_mod_rpart)

2:16
 [1]  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
visNetwork::visTree(summary_mod_rpart,
                    nodesPopSize = TRUE,
                    edgesFontSize = 18,
                    nodesFontSize = 20,
                    width = "100%",
                    height = "1200px")
NA
NA
NA
# Accuracy and other metrics
confusionMatrix(df_test$kickContactType, predictions2)
Confusion Matrix and Statistics

          Reference
Prediction   BB   BC   BF  BOG   CC CFFG  DEZ  ICC  KTB  KTC  KTF  MBC MBDR  OOB
      BB      6    0   18    0  471    5    0    0    0    0    0    0    0    0
      BC      0    1   10    0   40    0    0    0    0    0    0    0    0    0
      BF      7    1  224    0 1540   25    0    0    0    0    0    0    1    2
      BOG     0    0    1    0    9    0    0    0    0    0    0    0    0    0
      CC      4    0  140    0 6616   20    0    0    0    0    0    0    1    3
      CFFG    3    0   76    0  211   27    0    0    0    0    0    0    1    2
      DEZ     1    0    3    0  106    1    0    0    0    0    0    0    0    0
      ICC     0    0    0    0   32    0    0    0    0    0    0    0    0    0
      KTB     0    0    1    0   30    0    0    0    0    0    0    0    0    0
      KTC     0    0    1    0   61    0    0    0    0    0    0    0    0    0
      KTF     0    0    0    0   19    0    0    0    0    0    0    0    0    0
      MBC     1    0    1    0   11    0    0    0    0    0    0    0    0    0
      MBDR    0    0    5    0  231    1    0    0    0    0    0    0    0    0
      OOB     1    0   16    0  429    6    0    0    0    0    0    0    0    4

Overall Statistics
                                          
               Accuracy : 0.6597          
                 95% CI : (0.6505, 0.6688)
    No Information Rate : 0.9405          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.103           
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: BB  Class: BC Class: BF Class: BOG Class: CC Class: CFFG Class: DEZ Class: ICC Class: KTB Class: KTC
Sensitivity          0.2608696 0.50000000   0.45161         NA    0.6747    0.317647         NA         NA         NA         NA
Specificity          0.9525137 0.99520338   0.84129  0.9990409    0.7290    0.971666    0.98935   0.996931   0.997027   0.994053
Pos Pred Value       0.0120000 0.01960784   0.12444         NA    0.9752    0.084375         NA         NA         NA         NA
Neg Pred Value       0.9982873 0.99990361   0.96847         NA    0.1241    0.994261         NA         NA         NA         NA
Prevalence           0.0022060 0.00019183   0.04757  0.0000000    0.9405    0.008153    0.00000   0.000000   0.000000   0.000000
Detection Rate       0.0005755 0.00009591   0.02148  0.0000000    0.6346    0.002590    0.00000   0.000000   0.000000   0.000000
Detection Prevalence 0.0479570 0.00489162   0.17265  0.0009591    0.6507    0.030692    0.01065   0.003069   0.002973   0.005947
Balanced Accuracy    0.6066916 0.74760169   0.64645         NA    0.7019    0.644657         NA         NA         NA         NA
                     Class: KTF Class: MBC Class: MBDR Class: OOB
Sensitivity                  NA         NA   0.0000000  0.3636364
Specificity            0.998178   0.998753   0.9772618  0.9566011
Pos Pred Value               NA         NA   0.0000000  0.0087719
Neg Pred Value               NA         NA   0.9997056  0.9992979
Prevalence             0.000000   0.000000   0.0002877  0.0010551
Detection Rate         0.000000   0.000000   0.0000000  0.0003837
Detection Prevalence   0.001822   0.001247   0.0227316  0.0437368
Balanced Accuracy            NA         NA   0.4886309  0.6601187
LS0tCnRpdGxlOiAiRmluYWwgUHJvamVjdCBCaWcgRGF0YSBCb3dsIgphdXRob3I6ICJEYXJyb24gS290b3lhbiwgTmljIFZhbWlzLCBPYmFkYSBZb3NlZiIKc3VidGl0bGU6IE1HU0MgMzEwIFByb2JsZW0gU2V0IFRlbXBsYXRlCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQoKIyBQbGVhc2UgbGVhdmUgdGhpcyBjb2RlIGNodW5rIGFzIGlzLiBJdCBtYWtlcyBzb21lIHNsaWdodCBmb3JtYXR0aW5nIGNoYW5nZXMgdG8gYWx0ZXIgdGhlIG91dHB1dCB0byBiZSBtb3JlIGFlc3RoZXRpY2FsbHkgcGxlYXNpbmcuIAoKbGlicmFyeShrbml0cikKCiMgQ2hhbmdlIHRoZSBudW1iZXIgaW4gc2V0IHNlZWQgdG8geW91ciBvd24gZmF2b3JpdGUgbnVtYmVyCnNldC5zZWVkKDY5NjkpCm9wdGlvbnMod2lkdGg9NzApCm9wdGlvbnMoc2NpcGVuPTk5KQoKCiMgdGhpcyBzZXRzIHRleHQgb3V0cHV0dGVkIGluIGNvZGUgY2h1bmtzIHRvIHNtYWxsCm9wdHNfY2h1bmskc2V0KHRpZHkub3B0cz1saXN0KHdpZHRoLndyYXA9NTApLHRpZHk9VFJVRSwgc2l6ZSA9ICJ2c21hbGwiKSAgCm9wdHNfY2h1bmskc2V0KG1lc3NhZ2UgPSBGQUxTRSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLAogICAgICAgICAgICAgICAjICJjYWNoaW5nIiBzdG9yZXMgb2JqZWN0cyBpbiBjb2RlIGNodW5rcyBhbmQgb25seSByZXdyaXRlcyBpZiB5b3UgY2hhbmdlIHRoaW5ncwogICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIyBhdXRvbWF0aWNhbGx5IGRvd25sb2FkcyBkZXBlbmRlbmN5IGZpbGVzCiAgICAgICAgICAgICAgIGF1dG9kZXAgPSBUUlVFLAogICAgICAgICAgICAgICAjIAogICAgICAgICAgICAgICBjYWNoZS5jb21tZW50cyA9IEZBTFNFLAogICAgICAgICAgICAgICAjIAogICAgICAgICAgICAgICBjb2xsYXBzZSA9IFRSVUUsCiAgICAgICAgICAgICAgICMgY2hhbmdlIGZpZy53aWR0aCBhbmQgZmlnLmhlaWdodCB0byBjaGFuZ2UgdGhlIGNvZGUgaGVpZ2h0IGFuZCB3aWR0aCBieSBkZWZhdWx0CiAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDUuNSwgIAogICAgICAgICAgICAgICBmaWcuaGVpZ2h0ID0gNC41LAogICAgICAgICAgICAgICBmaWcuYWxpZ249J2NlbnRlcicpCgoKYGBgCgpgYGB7ciBzZXR1cC0yfQoKIyBBbHdheXMgcHJpbnQgdGhpcyBvdXQgYmVmb3JlIHlvdXIgYXNzaWdubWVudApzZXNzaW9uSW5mbygpCmdldHdkKCkKCmBgYAoKCjwhLS0gIyMjIHN0YXJ0IGFuc3dlcmluZyB5b3VyIHByb2JsZW0gc2V0IGhlcmUgLS0+CjwhLS0gWW91IG1heSBleHBvcnQgeW91ciBob21ld29yayBpbiBlaXRoZXIgaHRtbCBvciBwZGYsIHdpdGggdGhlIGZvcm1lciB1c3VhbGx5IGJlaW5nIGVhc2llci4gCiAgICAgVG8gZXhwb3J0IG9yIGNvbXBpbGUgeW91ciBSbWQgZmlsZTogY2xpY2sgYWJvdmUgb24gJ0tuaXQnIHRoZW4gJ0tuaXQgdG8gSFRNTCcgLS0+CjwhLS0gQmUgc3VyZSB0byBzdWJtaXQgYm90aCB5b3VyIC5SbWQgZmlsZSBhbmQgdGhlIGNvbXBpbGVkIC5odG1sIG9yIC5wZGYgZmlsZSBmb3IgZnVsbCBjcmVkaXQgLS0+CgoKYGBge3Igc2V0dXAtM30KCiMgbG9hZCBhbGwgeW91ciBsaWJyYXJpZXMgaW4gdGhpcyBjaHVuayAKbGlicmFyeSgnZHBseXInKQpsaWJyYXJ5KCd0aWR5dmVyc2UnKQpsaWJyYXJ5KCd1dGlscycpCmxpYnJhcnkoJ3JzYW1wbGUnKQpsaWJyYXJ5KCdnbG1uZXQnKQpsaWJyYXJ5KCdnbG1uZXRVdGlscycpCmxpYnJhcnkoJ2ZvcmNhdHMnKQpsaWJyYXJ5KCdyc2FtcGxlJykKbGlicmFyeSgnZ2dwbG90MicpCmxpYnJhcnkoJ3NqUGxvdCcpCmxpYnJhcnkoJ1B1Ymxpc2gnKQpsaWJyYXJ5KCdkYXRhLnRhYmxlJykKbGlicmFyeSgncHN5Y2gnKQpsaWJyYXJ5KCdwYXJ0eWtpdCcpCmxpYnJhcnkoJ1BlcmZvcm1hbmNlQW5hbHl0aWNzJykKbGlicmFyeSgncnBhcnQnKQpsaWJyYXJ5KCdycGFydC5wbG90JykKbGlicmFyeSgnbWFwdHJlZScpCmxpYnJhcnkoJ3JhbmRvbUZvcmVzdEV4cGxhaW5lcicpCmxpYnJhcnkoJ3JwYXJ0JykKbGlicmFyeSgndmlzTmV0d29yaycpCmxpYnJhcnkoJ2NhcmV0JykKbGlicmFyeSgnSVNMUicpCgoKIyBub3RlLCBkbyBub3QgcnVuIGluc3RhbGwucGFja2FnZXMoKSBpbnNpZGUgYSBjb2RlIGNodW5rLiBpbnN0YWxsIHRoZW0gaW4gdGhlIGNvbnNvbGUgb3V0c2lkZSBvZiBhIGNvZGUgY2h1bmsuIAoKYGBgCgoKYGBge3J9CnBsYXlzIDwtIHJlYWQuY3N2KGhlcmU6OmhlcmUoIkRhdGFzZXRzIiwgInBsYXlzLmNzdiIpKQpwZmYgPC0gcmVhZC5jc3YoaGVyZTo6aGVyZSgiRGF0YXNldHMiLCAiUEZGc2NvdXRpbmdkYXRhLmNzdiIpKQpoZWFkKHBmZikKCmBgYAoKYGBge3J9CgpERiA8LSBmdWxsX2pvaW4oeCA9IHBsYXlzLAogICAgICAgICAgICAgICAgIHkgPSBwZmYsCiAgICAgICAgICAgICAgICAgYnkgPSAiZ2FtZUlkIikKCkRGMiA9IHNlbGVjdChERiwgLTU6LTcsIC0xMDotMjEsIC0yNTotMjksIC0zMjotNDMpCgpERjIgJT4lIGRyb3BfbmEoKQoKREYyJHJldHVybl90eXBlW0RGMiRraWNrUmV0dXJuWWFyZGFnZSA8IDIwXSA9ICJTaG9ydCIKREYyJHJldHVybl90eXBlW0RGMiRraWNrUmV0dXJuWWFyZGFnZSA+IDIwICYgREYyJGtpY2tSZXR1cm5ZYXJkYWdlIDwgNTBdID0gIk1lZGl1bSIKREYyJHJldHVybl90eXBlW0RGMiRraWNrUmV0dXJuWWFyZGFnZSA+IDUwXSA9ICJMb25nIgoKRmluYWxERiA8LSBkYXRhLmZyYW1lKERGMiwgc3RyaW5nc0FzRmFjdG9ycyA9IFRSVUUpICU+JQogIGRyb3BfbmEoKSAlPiUKICBtdXRhdGUocmV0dXJuX3R5cGUgPSBhcy5mYWN0b3IocmV0dXJuX3R5cGUpLAogICAgICAgICBraWNrVHlwZSA9IGFzLmZhY3RvcihraWNrVHlwZSksCiAgICAgICAgIGtpY2tDb250YWN0VHlwZSA9IGFzLmZhY3RvcihraWNrQ29udGFjdFR5cGUpKQpoZWFkKEZpbmFsREYpCiAgCmBgYAoKCmBgYHtyfQoKc3VtbWFyeShGaW5hbERGKQoKYGBgCgpgYGB7cn0KCmdncGxvdChkYXRhID0gRmluYWxERiwgYWVzKHggPSBoYW5nVGltZSwgeSA9IGtpY2tMZW5ndGgpKSArIGdlb21fcG9pbnQoKQoKYGBgCgoKCmBgYHtyfQoKZ2dwbG90KGRhdGEgPSBGaW5hbERGLCBhZXMoeCA9IGtpY2tMZW5ndGgsIHkgPSBraWNrUmV0dXJuWWFyZGFnZSkpICsgZ2VvbV9wb2ludCgpCgpgYGAKCgpgYGB7cn0KCmdncGxvdChkYXRhID0gRmluYWxERiwgYWVzKHggPSByZXR1cm5fdHlwZSkpICsgZ2VvbV9iYXIoKQpgYGAKCgoKCgpgYGB7cn0KZGZfc3BsaXQgPC0gaW5pdGlhbF9zcGxpdChGaW5hbERGLCBwcm9wID0gMC43NSkKZGZfdHJhaW4gPC0gdHJhaW5pbmcoZGZfc3BsaXQpCmRmX3Rlc3QgPC0gdGVzdGluZyhkZl9zcGxpdCkKCmRpbShkZl90cmFpbikKZGltKGRmX3Rlc3QpCgptb2QxIDwtIGxtKGtpY2tSZXR1cm5ZYXJkYWdlIH4ga2lja0xlbmd0aCArIGhhbmdUaW1lICsga2lja0NvbnRhY3RUeXBlICsgcGxheVJlc3VsdCwKICAgICAgICAgICBkYXRhID0gZGZfdHJhaW4pCgpwbG90KHggPSBwcmVkaWN0KG1vZDEpLCB5ID0gZGZfdHJhaW4ka2lja1JldHVybllhcmRhZ2UsCiAgICAgeGxhYj0nUHJlZGljdGVkIFZhbHVlcycsCiAgICAgeWxhYj0nQWN0dWFsIFZhbHVlcycsCiAgICAgbWFpbj0nUHJlZGljdGVkIHZzLiBBY3R1YWwgVmFsdWVzIChUcmFpbmluZyBNb2RlbCknLAogICAgIGNvbD0gMSkKYWJsaW5lKGEgPSAwLCBiID0gMSkKCnByaW50KG1lYW4oKGRmX3RyYWluJGtpY2tSZXR1cm5ZYXJkYWdlIC0gcHJlZGljdChtb2QxKSleMikpCgpwbG90KHggPSBwcmVkaWN0KG1vZDEsIG5ld2RhdGEgPSBkZl90ZXN0KSwgeSA9IGRmX3Rlc3Qka2lja1JldHVybllhcmRhZ2UsCiAgICAgeGxhYj0nUHJlZGljdGVkIFZhbHVlcycsCiAgICAgeWxhYj0nQWN0dWFsIFZhbHVlcycsCiAgICAgbWFpbj0nUHJlZGljdGVkIHZzLiBBY3R1YWwgVmFsdWVzIChUZXN0aW5nIE1vZGVsKScsCiAgICAgY29sPSAxKQphYmxpbmUoYSA9IDAsIGIgPSAxKQoKcHJpbnQobWVhbigoZGZfdGVzdCRraWNrUmV0dXJuWWFyZGFnZSAtIHByZWRpY3QobW9kMSkpXjIpKQpgYGAKCmBgYHtyfQpwcmVkc190ZXN0IDwtIHByZWRpY3QobW9kMSwgbmV3ZGF0YSA9IGRmX3Rlc3QpCgpwcmVkc19kZiA8LSBkYXRhLmZyYW1lKAogIGBwcmVkaWN0ZWRfdmFsdWVzYCA9IHByZWRzX3Rlc3QsCiAgYGtpY2tfZGlzdGFuY2VfeWFyZHNgID0gZGZfdGVzdCRraWNrTGVuZ3RoCikKCmhlYWQocHJlZHNfZGYpCgpnZ3Bsb3QoZGF0YSA9IHByZWRzX2RmLCBhZXMoeCA9IGtpY2tfZGlzdGFuY2VfeWFyZHMsIHkgPSBwcmVkaWN0ZWRfdmFsdWVzKSkgKyBnZW9tX3BvaW50KCkgKyB0aGVtZV9taW5pbWFsKCkKCiN0b3RhbCA9IDEwNDI2CnByZWRzX2RmICU+JQogIGNvdW50KHByZWRpY3RlZF92YWx1ZXMgPiA1MCkgIzE0OCwgMS40JQoKcHJlZHNfZGYgJT4lCiAgY291bnQocHJlZGljdGVkX3ZhbHVlcyA8IDIwKSAjNzE2MCwgNjguNyUKCnByZWRzX2RmICU+JQogIGNvdW50KGJldHdlZW4ocHJlZGljdGVkX3ZhbHVlcywgMjAsIDUwKSkgIzMxMTgsIDI5LjklCgpgYGAKCgpgYGB7cn0KCmxpYnJhcnkoJ3NwYXJrbGluZScpCgoKc3VtbWFyeV9tb2RfcnBhcnQgPC0gcnBhcnQocmV0dXJuX3R5cGUgfiBraWNrTGVuZ3RoICsgaGFuZ1RpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl90cmFpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gImNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoY3AgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5zcGxpdCA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhkZXB0aCA9IDUpKQpzdW1tYXJ5X21vZF9ycGFydCRjcHRhYmxlCgpwbG90Y3Aoc3VtbWFyeV9tb2RfcnBhcnQpCjI6MTYKdmlzTmV0d29yazo6dmlzVHJlZShzdW1tYXJ5X21vZF9ycGFydCwKICAgICAgICAgICAgICAgICAgICBub2Rlc1BvcFNpemUgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIGVkZ2VzRm9udFNpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICBub2Rlc0ZvbnRTaXplID0gMjAsCiAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAiMTAwJSIsCiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gIjEyMDBweCIpCgoKCmBgYAoKCgoKYGBge3J9CgpsaWJyYXJ5KCdyYW5kb21Gb3Jlc3QnKQoKbW9kZml0LnJmIDwtIHJhbmRvbUZvcmVzdChraWNrQ29udGFjdFR5cGUgfiAga2lja0xlbmd0aCArIGhhbmdUaW1lLCBkYXRhPWRmX3RyYWluKQoKIyBQcmVkaWN0IHRoZSB0ZXN0aW5nIHNldCB3aXRoIHRoZSB0cmFpbmVkIG1vZGVsCnByZWRpY3Rpb25zMiA8LSBwcmVkaWN0KG1vZGZpdC5yZiwgZGZfdGVzdCwgdHlwZSA9ICJjbGFzcyIpCgojIEFjY3VyYWN5IGFuZCBvdGhlciBtZXRyaWNzCmNvbmZ1c2lvbk1hdHJpeChkZl90ZXN0JGtpY2tDb250YWN0VHlwZSwgcHJlZGljdGlvbnMyKQoKCiNyZl9maXQgPC0gcmFuZG9tRm9yZXN0KGtpY2tDb250YWN0VHlwZSB+IAojICAgICAgICAgICAgICAgICAgICAgIGtpY2tMZW5ndGggKyBoYW5nVGltZSwgCiAjICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3RyYWluLAogIyAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBjbGFzc2lmaWNhdGlvbiwKICMgICAgICAgICAgICAgICAgICAgICAgbXRyeSA9IDQsCiAgIyAgICAgICAgICAgICAgICAgICAgIG5hLmFjdGlvbiA9IG5hLnJvdWdoZml4LAogICMgICAgICAgICAgICAgICAgICAgICBudHJlZSA9IDYwLCAKICAgIyAgICAgICAgICAgICAgICAgICAgaW1wb3J0YW5jZSA9IFRSVUUpCgojcHJpbnQocmZfZml0KQoKI3Bsb3QocmZfZml0KQoKCgojdHJlZV9tb2QyIDwtIGN0cmVlKGtpY2tDb250YWN0VHlwZSB+IGtpY2tMZW5ndGggKyBoYW5nVGltZSwKIyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl90cmFpbikKCiNwcmludCh0cmVlX21vZDIpCiNwbG90KHRyZWVfbW9kMikgCgoKI21vZDIgPC0gbG0obG9nKGtpY2tDb250YWN0VHlwZSkgfiBraWNrTGVuZ3RoICsgaGFuZ1RpbWUsIAogICAgICAgICAgICNkYXRhID0gZGZfdHJhaW4pCiNzdW1tYXJ5KG1vZDIpCgojbW9kZml0LnJwYXJ0IDwtIHJwYXJ0KGNsYXNzZSB+IC4sIGRhdGE9dHJhaW5pbmcsIG1ldGhvZD0iY2xhc3MiLCB4dmFsID0gNCkKI3ByaW50KG1vZGZpdC5ycGFydCwgZGlnaXRzID0gMykKCiNwcmVkaWN0aW9uczEgPC0gcHJlZGljdChtb2RmaXQucnBhcnQsIHRlc3RpbmcsIHR5cGUgPSAiY2xhc3MiKQoKIyBBY2N1cmFjeSBhbmQgb3RoZXIgbWV0cmljcwojY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25zMSwgdGVzdGluZyRjbGFzc2UpCgpgYGAKCgo=